iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
Mobile Development

30天 - Flutter 日常系列 第 12

[Day12] Flutter - 場景路徑與轉換 ( Auto Router )

  • 分享至 

  • xImage
  •  

前言

Hi, 我是魚板伯爵今天要教大家 Auto Router 這個套件,教學內容只會擷取片段程式碼,建議大家搭配完整程式碼來練習。

完整程式碼

有時候App需要切換很多個頁面,或者太多頁面的路徑常常很難找出錯誤,我們可以使用Autorouter來幫助我們簡化程式碼,如果有哪個路徑不對,只需要檢查我們設定的參數是否有錯誤就可以了。

安裝套件

auto_route為我們這次主要的套件,而auto_route_generatorbuild_runner是為了可以生成我們路由的套件。

dependencies:
  flutter:
    sdk: flutter
  auto_route: ^2.3.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner:
  auto_route_generator: ^2.1.0

AutoRouter 常用屬性

完成以下的的路由設定後,在終端機(Terminal)上執行flutter pub run build_runner watch --delete-conflicting-outputs指令就會生成出router.gr.dart的檔案。

  • initial:預設路徑
  • page:頁面
  • path:自訂路徑
  • children:子路徑

router.dart

import 'package:auto_route/auto_route.dart';
import 'package:day12/demo.dart';
import 'package:day12/transitions.dart';

// flutter pub run build_runner watch --delete-conflicting-outputs

@MaterialAutoRouter(
  replaceInRouteName: 'Page,Route',
  routes: <AutoRoute>[
    AutoRoute(path: '/', page: LoginScreen, initial: true),
    AutoRoute(path: '/home-screen', page: HomeScreen),
  ],
)
class $AppRouter {}

主界面初始化路由

main.dart

import 'package:day12/demo.dart';
import 'package:day12/router.gr.dart';
import 'package:flutter/material.dart';

void main() {
  final AppRouter appRouter = AppRouter();
  runApp(
    MyApp(
      appRouter: appRouter,
    ),
  );
}

class MyApp extends StatelessWidget {
  final AppRouter _appRouter;

  MyApp({
    Key? key,
    required AppRouter appRouter,
  })  : _appRouter = appRouter,
        super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routerDelegate: _appRouter.delegate(),
      routeInformationParser: _appRouter.defaultRouteParser(),
      builder: (context, router) => router!,
    );
  }
}

如何轉場

首先所有的場景都會在Stack裡,利用replacenavigatepushpop,來控制所有頁面的進出。若後面有加上Named的元件則代表使用自己所定義的path來控制路由。

  • replace:覆蓋原本的頁面
  • navigate:如果沒在stack就加入
  • push:加入一個新的介面在stack
  • pop:退出stack
class LoginScreen extends StatelessWidget {
  const LoginScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("LoginScreen"),
      ),
      backgroundColor: Colors.indigo[50],
      body: Center(
        child: TextButton(
          child: Text("Sign in"),
          onPressed: () {
            // 轉場
            AutoRouter.of(context).replaceNamed("/home-screen");
          },
        ),
      ),
    );
  }
}

CustomRoute 使用其他的轉場動畫

  • transitionsBuilder:轉場動畫設定
  • durationInMilliseconds:轉場動畫時間
@MaterialAutoRouter(
  replaceInRouteName: 'Page,Route',
  routes: <AutoRoute>[
    AutoRoute(path: '/', page: LoginScreen, initial: true),
    AutoRoute(path: '/home-screen', page: HomeScreen),
    CustomRoute(
      path: '/menu-screen',
      page: MenuScreen,
      transitionsBuilder: TransitionsBuilders.fadeIn,
      durationInMilliseconds: 1000,
    ),
  ],
)
class $AppRouter {}

使用自己的轉場動畫

我們可以用transitionsBuilder來寫自己的轉場動畫,至於如何控制就交給大家自己摸索了,以下就寫一個簡單的範例給大家參考。

@MaterialAutoRouter(
  replaceInRouteName: 'Page,Route',
  routes: <AutoRoute>[
    AutoRoute(path: '/', page: LoginScreen, initial: true),
    AutoRoute(path: '/home-screen', page: HomeScreen),
    CustomRoute(
      path: '/menu-screen',
      page: MenuScreen,
      transitionsBuilder: MyTransitions.slideBottomToTop,
      durationInMilliseconds: 1000,
    ),
  ],
)
class $AppRouter {}
class MyTransitions extends TransitionsBuilders {
  static const RouteTransitionsBuilder slideBottomToTop = _slideBottomToTop;

  static Widget _slideBottomToTop(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget child,
  ) {
    return SlideTransition(
      position: Tween<Offset>(
        begin: const Offset(0, 1),
        end: Offset.zero,
      ).animate(animation),
      child: child,
    );
  }
}

Note:

由於是Gif的緣故可能有點卡頓的感覺。


上一篇
[Day11] Flutter - StatelessWidget & StatfulWidget 差別
下一篇
[Day13] Flutter - 管理程式碼好幫手 ( Bloc )
系列文
30天 - Flutter 日常30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言